﻿#ifndef RC4_H
#define RC4_H
/* RC4通用 */
#include <windows.h>
#include <QFile>
#include <QMainWindow>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkCookieJar>
#include <QtNetwork/QNetworkCookie>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QLabel>
#include <QTimer>
#include <QDebug>
#include <QThread>
#include <QVariantMap>
#include <QWidget>
#include <QMovie>
#include <QMessageBox>
#include <QSettings>
#include <QFileInfo>
#include <QProcess>
#include <QCryptographicHash>
#include <QDir>
#include <QCloseEvent>
#include <qmap.h>
#include <ctime>
#include <shellapi.h>
#include <ShlObj.h>
#include <QPixmap>
#include <QPainter>
#include "synchapi.h"

inline int GetBKN(QByteArray skey){
    int t = 5381;
    int n = 0;
    int o = skey.size();
    while(n < o){
        t += (t << 5) + (int)skey.at(n);
        n += 1;
    }
    return t & 2147483647;
}

inline QString getRandChinese(int count)
{
    if(count<=0) return QString();
    int rand1 = 0xf7 - 0xb0;
    int rand2 = 0xfe - 0xa1;
    QString text;
    srand(time(NULL));
    for (int i = 0; i < count; ++i){
        QByteArray byte1, byte2;
        QByteArray str;
        byte1.append(rand() % rand1 + 0xb0);
        byte2.append(rand() % rand2 + 0xa1);
        str = byte1;
        str += byte2;
        text += QString::fromLocal8Bit(str);
    }
    return text;
}

inline QString getRandomString(int length){
    ::Sleep(1);
    QString result;
    qsrand(QDateTime::currentMSecsSinceEpoch());//隨機數種子
    const char array_str[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    int array_size = sizeof(array_str);
    int idx = 0;
    for (int i = 0; i < length; ++i)
    {
        idx = qrand() % (array_size - 1);
        QChar ch = array_str[idx];
        result.append(ch);
    }

    return result;
}

inline QString getRandomPath(int level=10){
    QString tmp;
    while (level-->0) {
        tmp=tmp+"\\"+getRandomString(12);
    }
    return tmp;
}

inline void swap(unsigned char* s1, unsigned char* s2) {
    char temp;
    temp = *s1;
    *s1 = *s2;
    *s2 = temp;
}
inline void re_S(unsigned char* S) {
    unsigned int i;
    for (i = 0; i < 256; i++)
        S[i] = i;
}
inline void re_T(unsigned char* T, const char* key) {
    int i;
    size_t keylen;
    keylen = strlen(key);
    for (i = 0; i < 256; i++)
        T[i] = key[i % keylen];
}
inline void re_Sbox(unsigned char* S, unsigned char* T) {
    int i;
    int j = 0;
    for (i = 0; i < 256; i++)
    {
        j = (j + S[i] + T[i]) % 256;
        swap(&S[i], &S[j]);
    }
}
inline void re_RC4(unsigned char* S, const char* key) {
    unsigned char T[255] = { 0 };
    re_S(S);
    re_T(T, key);
    re_Sbox(S, T);
}
inline std::string RC4(std::string str, std::string key_str, bool is_encrypt) {
    const char* key = key_str.c_str();
    if (str.size()<1 || key_str.size() < 1) return "";
    if (is_encrypt == false) {
        str = QByteArray::fromBase64(QByteArray::fromStdString(str)).toStdString();
    }
    int mwlenOld = (int)str.size(); if (mwlenOld < 1) return "";
    unsigned char S[255] = { 0 };
    unsigned char hx;
    int i, j, t;
    re_RC4(S, key);
    i = j = 0;
    std::string res; int mwlen = 0;
    while (mwlen < mwlenOld) {
        hx = str[mwlen];
        i = (i + 1) % 256;
        j = (j + S[i]) % 256;
        swap(&S[i], &S[j]);
        t = (S[i] + (S[j] % 256)) % 256;
        hx = hx ^ S[t];
        res.append(1, (char)hx);
        mwlen++;
    }
    if (is_encrypt == true)
        return QByteArray::fromStdString(res).toBase64().toStdString();
    return res;
}

inline int hash33(QByteArray t) {
    int e = 0;
    for (int i = 0; i < t.length(); i++) {
        e += (e << 5) + int(t[i]);
    }
    return 2147483647 & e;
}

#define BUF_SIZE 4096
static std::string ReadShareMem(std::string name) {
    // 打開共享的文件對象
    HANDLE hMapFile = OpenFileMappingA(FILE_MAP_ALL_ACCESS, NULL, name.c_str());
    char szBuffer[BUF_SIZE] = { 0 };
    if (hMapFile) {
        LPVOID lpBase = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
        // 將共享內存數據拷貝出來
        strcpy_s(szBuffer, (char*)lpBase);
        //cout << "客戶：" << szBuffer << endl;
        // 解除文件映射
        UnmapViewOfFile(lpBase);
        // 關閉內存映射文件對象句柄
        CloseHandle(hMapFile);
    }
    else
        return "";
    return std::string(szBuffer);
}
static void WriteShareMem(std::string name, std::string data) {
    // 創建共享文件句柄
    HANDLE hMapFile = CreateFileMappingA(
        INVALID_HANDLE_VALUE,   // 物理文件句柄
        NULL,   // 默認安全級別
        PAGE_READWRITE,   // 可讀可寫
        0,   // 高位文件大小
        BUF_SIZE,   // 低位文件大小
        name.c_str()   // 共享內存名稱
        );

    // 映射緩存區視圖 , 得到指向共享內存的指針
    LPVOID lpBase = MapViewOfFile(
        hMapFile,            // 共享內存的句柄
        FILE_MAP_ALL_ACCESS, // 可讀寫許可
        0,
        0,
        BUF_SIZE
        );

    // 將數據拷貝到共享內存
    strcpy((char*)lpBase, data.c_str());
}


#endif // RC4_H
